<template>
    <div id="xitong-container" style="position: relative; width: 1000px; min-height: 400px; padding: 20px 12px">
        <div style="position: absolute; top: 0; left: 0; width: 100%; height: 20px; padding: 0 24px; font-weight: bold">
            <flexbox>
                <a-tag color="#657BA3">父需求</a-tag>
                <a-tag color="#0176D3">业务需求</a-tag>
                <a-tag color="#FB7555">产品需求</a-tag>
            </flexbox>
        </div>
    </div>
</template>

<script lang="ts">
import G6 from '@antv/g6';
import { defineComponent, ref, unref, reactive, toRefs, onMounted } from 'vue';
export default defineComponent({
    props: {
        detail: {
            type: Object,
            default: () => ({})
        }
    },
    setup(props) {
        const state = reactive<any>({
            data: [],
            deepLevel: 1 // 树的深度
        });
        // 文本超出隐藏 (字段, 最大长度, 字体大小)
        const fittingString = (str, maxWidth, fontSize) => {
            const ellipsis = '...';
            const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0];
            let currentWidth = 0;
            let res = str;
            const pattern = new RegExp('[\u4E00-\u9FA5]+'); // distinguish the Chinese charactors and letters
            str.split('').forEach((letter, i) => {
                if (currentWidth > maxWidth - ellipsisLength) {return}
                if (pattern.test(letter)) {
                    // Chinese charactors
                    currentWidth += fontSize;
                } else {
                    // get the width of single letter according to the fontSize
                    currentWidth += G6.Util.getLetterWidth(letter, fontSize);
                }
                if (currentWidth > maxWidth - ellipsisLength) {
                    res = `${str.substr(0, i)}${ellipsis}`;
                }
            });
            return res;
        };
        // 获取文本的长度
        const getColor = (node) => {
            if (node.isRequire) {
                return '#FB7555';
            } else {
                if (node.isFather) {
                    return '#657BA3';
                } else {
                    if (node.id == props.detail.id) {
                        return '#0176D3';
                    }
                    return 'rgba(135,170,239)';
                }
            }
        };
        const getNodeSize = (node) => {
            if (state.deepLevel === 1) {
                return 14;
            } else if (state.deepLevel === 2 && state.data.children.length <= 2) {
                return 30;
            } else {
                return node.isRequire ? 40 : 50;
            }
        };
        const getLabelSize = (node) => {
            if (state.deepLevel === 1) {
                return 2;
            } else if (state.deepLevel === 2 && state.data.children.length <= 2) {
                return 4;
            } else {
                return 6;
            }
        };
        const tooltip = new G6.Tooltip({
            offsetX: 40,
            offsetY: 10,
            getContent(e: any) {
                const outDiv = document.createElement('div');
                outDiv.style.width = '180px';
                outDiv.innerHTML = `<span>需求名称：${e.item.getModel().name}</span></br><span>需求类型：${e.item.getModel().isRequire ? '产品需求' : '业务需求'}</span>`;
                return outDiv;
            },
            itemTypes: ['node']
        });
        const init = () => {
            const container: any = document.getElementById('xitong-container');
            const width = container.scrollWidth;
            const height = container.scrollHeight || 500;
            const graph = new G6.TreeGraph({
                container: 'xitong-container',
                width,
                height,
                plugins: [tooltip],
                modes: {
                    default: []
                },
                // 默认节点配置
                defaultNode: {
                    size: 50,
                    anchorPoints: [
                        [0, 0.5],
                        [1, 0.5]
                    ],
                    style: {
                        cursor: 'pointer',
                        fill: '#0176d3',
                        stroke: '#0176d3'
                    }
                },
                // 默认边
                defaultEdge: {
                    type: 'polyline', // 折线
                    color: 'rgba(0,0,0,0.1)',
                    style: {
                        lineWidth: 1
                    }
                },
                layout: {
                    type: 'compactBox',
                    direction: 'LR', // H / V / LR / RL / TB / BT
                    getId: function getId(d) {
                        return d.id;
                    },
                    getHeight: function getHeight() {
                        return 16;
                    },
                    getWidth: function getWidth() {
                        return 16;
                    },
                    getVGap: function getVGap() {
                        return 20;
                    },
                    getHGap: function getHGap() {
                        return 100;
                    }
                }
            });

            graph.node((node: any) => {
                return {
                    label: fittingString(node.name, 110, 16),
                    labelCfg: {
                        position: 'center',
                        style: {
                            fontSize: getLabelSize(node),
                            fill: '#fff'
                        }
                    },
                    size: getNodeSize(node),
                    style: {
                        fill: getColor(node),
                        stroke: getColor(node)
                    }
                };
            });

            graph.data(state.data);
            graph.render();
            graph.fitView();

            if (typeof window !== 'undefined')
            {window.onresize = () => {
                if (!graph || graph.get('destroyed')) {return}
                if (!container || !container.scrollWidth || !container.scrollHeight) {return}
                graph.changeSize(container.scrollWidth, container.scrollHeight);
            };}
        };
        onMounted(() => {
            // 产品需求
            if (props.detail.requireName) {
                let data: any = {};
                if (props.detail.sonRequestInfos) {
                    // 是否有父需求
                    if (props.detail.fatherRequestInfo) {
                        const fRInfo = props.detail.fatherRequestInfo;
                        data = {
                            name: fRInfo.requestName,
                            id: fRInfo.id.toString(),
                            isFather: true,
                            children: []
                        };
                        const sonRInfo = props.detail.sonRequestInfos;
                        sonRInfo.forEach((item) => {
                            const obj: any = {
                                id: item.id.toString(),
                                name: item.requestName
                            };
                            if (props.detail.relateRequireId === item.id) {
                                obj.children = [
                                    {
                                        id: props.detail.id.toString(),
                                        name: props.detail.requireName,
                                        isRequire: true
                                    }
                                ];
                            }
                            data.children.push({
                                ...obj
                            });
                        });
                        state.deepLevel = 3;
                    }
                    // 没有父需求
                    else {
                        data = {
                            name: props.detail.sonRequestInfos[0].requestName,
                            id: props.detail.sonRequestInfos[0].id.toString(),
                            children: [
                                {
                                    id: props.detail.id.toString(),
                                    name: props.detail.requireName,
                                    isRequire: true
                                }
                            ]
                        };
                        state.deepLevel = 2;
                    }
                }
                // 无业务需求
                else {
                    data = {
                        name: props.detail.requireName,
                        id: props.detail.id.toString(),
                        isRequire: true
                    };
                    state.deepLevel = 1;
                }
                state.data = data;
                init();
            } else {
                // 业务需求
                if (props.detail.pmpProductRequires) {
                    let data: any = {};
                    // 产品需求数据结构
                    const pmpProductRequires = props.detail.pmpProductRequires.map((item) => ({
                        id: item.id.toString(),
                        name: item.requireName,
                        isRequire: true
                    }));
                    if (props.detail.fatherRequestInfo) {
                        const fRInfo = props.detail.fatherRequestInfo;
                        data = {
                            name: fRInfo.requestName,
                            id: fRInfo.id.toString(),
                            isFather: true,
                            children: []
                        };
                        const sonRInfo = [...props.detail.brotherRequestInfos, { id: props.detail.id, requestName: props.detail.requestName }];
                        sonRInfo.forEach((item) => {
                            const obj: any = {
                                id: item.id.toString(),
                                name: item.requestName
                            };
                            if (props.detail.id === item.id) {
                                obj.children = pmpProductRequires;
                            }
                            data.children.push({
                                ...obj
                            });
                        });
                        state.deepLevel = 3;
                    } else {
                        data = {
                            name: props.detail.requestName,
                            id: props.detail.id.toString(),
                            children: pmpProductRequires
                        };
                        state.deepLevel = pmpProductRequires.length ? 2 : 1;
                    }
                    state.data = data;
                    init();
                }
            }
        });
    }
});
</script>

<style scoped>
</style>